<template>
  <div class="container">
    <div class="title_bar">
      <div class="main_title">销量统计表</div>
      <div class="sub_title">1901 - 1914 服装销量统计表</div>
      <slot name="title"></slot>
    </div>
    <div id="funnel_basic" style="width: 100%"></div>
  </div>
</template>

<script>
import { Chart } from "@antv/g2";
import { DataView } from "@antv/data-set";
export default {
  data() {
    return {
      chart: null,
      dataList: [
        { type: "衣服", nums: 28 },
        { type: "裤子", nums: 32 },
        { type: "衬衫", nums: 40 },
        { type: "毛衣", nums: 18 },
        { type: "T恤", nums: 52 },
        { type: "围巾", nums: 15 },
        { type: "帽子", nums: 8 },
        { type: "皮鞋", nums: 11 }
      ],
    };
  },
  mounted() {
    this.chart = new Chart({
      // 指定图表容器 ID
      container: "funnel_basic",
      // 自适应宽度，容器伸缩会重新渲染图表
      autoFit: true,
      // 容器的高度
      height: 500,
      // 图表的外侧内边距
      padding: [40, 80, 80, 80],
    });

    this.chart.data(this.transformData(this.dataList));
    // 漏斗图其实就是变换坐标系和图形的柱状图
    this.chart
      .coordinate("rect")
      // x 轴 与 y 轴置换
      .transpose()
      // 同 transform 的 scale ,这里将 y 坐标变化为 -y
      .scale(1, -1);
    // 不显示坐标轴
    this.chart.axis(false);

    this.chart.tooltip({
      // 不显示 Marker 点
      showMarkers: false,
    });

    this.chart.interaction("element-active");
    this.chart
      .interval()
      .position("type*nums")
      // 数据居中对齐
      .adjust("symmetric")
      // 图形设置为三角形
      .shape("pyramid")
      .color("type");
    // 这里解决 pyramid label 无法正常居中的问题。
    // 这里使用的方法是动态 annotation 通过计算 position 动态更新 annotation
    this.chart.on("beforepaint", () => {
      // beforepaint 的时候清楚图表的 annotation
      this.chart.annotation().clear(true);
      // 获取图表的 data 数据
      const chartData = this.chart.getData();
      const dataLength = chartData.length;
      // 计算每个文本的在相对图形上 Y 方向的位移（offsetY）。计算方法：总的图表高度 / 数据长度 / 2
      const geometriesGap = this.chart.coordinateBBox.height / dataLength / 2;
      console.log('geometriesGap',geometriesGap)
      // 中间标签文本
      chartData.forEach((obj,index) => {
        // 绘制文本标注
        this.chart.annotation().text({
          top: true,
          // 计算每个文本标注的位置。由于图表是在 Y 方向上排列，x为50% 横线居中，y 根据每个图形的位置动态计算百分比。计算完的文本会紧贴相对应图形的顶部。
          position:["50%",(index/dataLength)*100 + "%"],
          // 在给 Y 方向的 offset 的值是的文本相对于图形整体居中。移动的距离是图形的高度的一半 - 字体大小的一半。
          offsetY: geometriesGap - 6,
          // 文本内容
          content: (+obj.percent * 100).toFixed(2) + "%", // 显示的文本内容
          // 绘图属性
          style: {
            stroke: null,
            fill: "#fff",
            textAlign: "center",
            fontSize:12
          },
        });
      });
    });
    // 渲染图表
    this.chart.render();
  },
  watch: {
    // 监听图表变化更新数据
    dataList(newValue) {
      console.log(newValue);
      this.chart.changeData(this.transformData(newValue));
    },
  },
  methods: {
    // 数据变换
    transformData() {
      const dv = new DataView().source(this.dataList);
      dv.transform({
        type: "sort",
        callback(a, b) {
          return b.nums - a.nums;
        },
      }).transform({
        type: "percent",
        field: "nums",
        dimension: "type",
        as: "percent",
      });
      return dv.rows;
    },
  },
};
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  .title_bar {
    width: 100%;
    margin-bottom: 20px;
    .main_title {
      width: 100%;
      text-align: center;
      font-size: 40px;
      color: #333333;
    }
    .sub_title {
      width: 100%;
      text-align: center;
      font-size: 28px;
      margin-top: 18px;
      color: #999999;
    }
  }
}
</style>